<cfcomponent displayname="ReactorAdapter" extends="actionpacks.persistence.PersistenceService" output="false">

	<cffunction name="init" returntype="any" output="false" hint="Constructor">
		<cfargument name="ORMService" required="true">
		<cfset variables.instance.ORMService = arguments.ORMService />
		<cfreturn this />
	</cffunction>

	<cffunction name="setORMService" access="public" returntype="any" output="false" roles="" hint="Import: ORM Service">
		<cfargument name="ORMService"  required="true" type="any" />
		<cfset variables.instance.ORMService = arguments.ORMService />
	</cffunction>

	<cffunction name="getORMService" access="private" returntype="any" output="false" roles="" hint="Returns Internal: ORM Service">
		<cfreturn variables.instance.ORMService />
	</cffunction>

	<cffunction name="getObjectFields" access="private" output="false" returntype="any" >
		<cfargument name="persistedObject" required="true" />
		<cfset var ormobjectname = getMetaORM(arguments.persistedObject)>
		<cfset var fields = getORMService().createMetadata(ormobjectname).getFieldQuery() />
		<cfreturn fields />
	</cffunction>

	<cffunction name="getObjectPrimaryKey" access="private" output="false" returntype="any" >
		<cfargument name="persistedObject" required="true" />
		<cfset var fields = getObjectFields(arguments.persistedObject) />
		<cfset var priKey = "">
		<cfloop query="fields">
		  <cfif primaryKey>
				<cfset priKey = alias>
			</cfif>
		</cfloop>
		<cfreturn priKey />
	</cffunction>

	<cffunction name="getGateway" access="public" output="false" returntype="any">
		<cfargument name="persistedObject" required="true" />
		<cfscript>
			var ormName = getMetaORM(arguments.persistedObject);
			var gateway = getORMService().createGateway(ormName);
			return gateway;
		</cfscript>
	</cffunction>

	<cffunction name="getRecord" access="public" output="false" returntype="any">
		<cfargument name="persistedObject"  required="true" />
		<cfscript>
			var ormName = getMetaORM(arguments.persistedObject);
			var record = getORMService().createRecord(ormName);			
			return record;
		</cfscript>
	</cffunction>

	<cffunction name="persist" returntype="any" access="public" output="false">
		<cfargument name="persistObject" type="any" required="true" hint="object to persist"/>
		<cfargument name="useTransaction" type="boolean" default="false" />
		<cfscript>
			var recordOb = getRecord(arguments.persistedObject);
			var popRec = recordOb.populate(persistObject);
			var record = recordOb.load();
			var errors = "";
			var dict = "";
			var errorCollection = createObject("component", "ModelGlue.Util.ValidationErrorCollection").init();
			var x = 0;
			record.validate();

			if(NOT record.hasErrors()) {
				record.save(arguments.useTransaction);
			} 
			else {
				errors = record._getErrorCollection().getErrors();
				dict = record._getDictionary();
				for(x=1; x lte arrayLen(errors); x = x+1) {
					errorCollection.addError(listGetAt(errors[x], 2, "."), dict.getValue(errors[x]));
				}
			}
//			dumpvar(record._getTo());
			return errorCollection.getErrors();
		</cfscript>
	</cffunction>

	<cffunction name="persisted" returntype="any" output="false" hint="Create Project Object">
		<cfargument name="persistedObject" type="any" required="true" hint="object to persist"/>
		<cfargument name="useTransaction" type="boolean" default="false" />
		<cfscript>
			var record = getRecord(arguments.persistedObject);
			populate(record,persistedObject,true);
			record.load();
			populate(arguments.persistedObject,record);
			return persistedObject;
		</cfscript>
	</cffunction>


	<cffunction name="createObjectWhere" returntype="any" access="public" output="false">
		<cfargument name="persistedObject" type="any" required="true" hint="object to persist"/>
		<cfargument name="reactorQuery" type="any" required="true" hint="object to persist"/>
		<cfscript>
			var query = arguments.reactorQuery;
			var ormobjectname = getMetaORM(persistedObject);
		 	var objectFunctionArray = StructKeyArray(arguments.persistedObject);
		 	var fields = getObjectFields(arguments.persistedObject);		 	
		 	var funk = "";
		 	var x = "";
		 	var value = "";
		 	var whereMethods = "isLike,isEqual,isGreaterThan,isLessThan";
		 	var whereMethodArgs = structNew();
	  </cfscript>
	  <cfloop query="fields">
		  <cfloop from="1" to="#ArrayLen(objectFunctionArray)#" index="x">
			  <cfset funk = lcase(objectFunctionArray[x]) />
				<cfif left(funk, 3) IS "get" AND (right(funk,len(funk)-3) IS lcase(alias))>
						<cfinvoke component="#arguments.persistedObject#" method="#funk#" returnvariable="value" />
						<cfif value gt "">
						  <cfif findNoCase("|",value)>
						  <cfdump var="#value#"><cfabort />
							</cfif>
							<cfif listFindNoCase(whereMethods,listFirst(value,"|"))>
								<!--- check for a specific whereMethod --->
							  <cfset whereMethod = listFirst(value,"|")>
							  <cfset value = replacenocase(value,"|#whereMethod#|","") />
							  <cfset whereMethodArgs["ormobjectname"] = ormobjectname />
							  <cfset whereMethodArgs["alias"] = alias />
							  <cfset whereMethodArgs["value"] = value />
							  <cfdump var="#value#"><cfabort />
								<cfinvoke component="#query.getWhere()#" method="#whereMethod#" argumentcollection="#whereMethodArgs#" />
							<cfelse>
								<!--- determine the type of whereMethod by datatype --->
									<cfswitch expression="#cfdatatype#">
									  <cfcase value="string">
				 							<cfset query.getWhere().isLike(ormobjectname,alias,value) />
										</cfcase>
									  <cfcase value="numeric">
				 							<cfset query.getWhere().isEqual(ormobjectname,alias,value) />
										</cfcase>
										<cfdefaultcase>
				 							<cfset query.getWhere().isEqual(ormobjectname,alias,value) />
										</cfdefaultcase>
									</cfswitch>
							</cfif>
						</cfif>
				</cfif>
			</cfloop>
		</cfloop>
		<cfreturn query />			
	</cffunction>

	<cffunction name="query" returntype="any" access="public" output="false">
		<cfargument name="persistedObject" type="any" required="true" hint="object to persist"/>
		<cfargument name="objectIds" type="any" default="" hint="object ids for multiples"/>
		<cfscript>
			var statusNames = structNew();
			var dataGW = getGateway(arguments.persistedObject);
			var query = dataGW.createquery();
			var priKey = "";
			var ormobjectname = getMetaORM(persistedObject);
	 	  // query.returnObjectFields("projects", "projectId,projectName");
 			//query.getWhere().isEqual("projectticketstatuses", "projectId", arguments.projectId);
 			query = createObjectWhere(persistedObject,query);
 			if(arguments.objectIds gt "") {
 				priKey = getObjectPrimaryKey(arguments.persistedObject);
 				query.getWhere().isIn(ormobjectname,priKey,arguments.objectIds);
 			}
			query = dataGW.getByQuery(query);
//	 	  return listToArray(valueList(query.statusName));
			return query;
		</cfscript>
	</cffunction>

</cfcomponent>